﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using System.Drawing.Drawing2D;

namespace nsGumController
{
    public partial class DockSetParameter : DockContent
    {
        private CLog mLog = CGumController.mLog;
        public BindingList<ActionParas> mAutoActionList = new BindingList<ActionParas>();
        public int originXSet;
        public int originYSet;
        public uint pwmCycleTDefault;
        public uint pwmCycleTGum;
        public uint pwmCycleTReset;
        public uint pwmCycleTChabu;
        public uint pwmChabuDelay;

        public DockSetParameter()
        {
            InitializeComponent();
            originXSet = 0;
            originYSet = 0;
            pwmCycleTDefault = 666;
            pwmCycleTReset = 300;
            pwmCycleTChabu = 666;
            pwmCycleTGum = 100;
            pwmChabuDelay = 1000;
        }

        /// <summary>
        /// 重写以float方式显示的dock窗体的show方法
        /// 区分是否第一次显示，DefaultFloatWindowSize只在第一次显示的时候有效，窗口hide后再显示时候不再指定显示类型
        /// 这样多个float的大小设置不会相互影响。
        /// </summary>
        private bool isFirstShow = true;
        new public void Show(DockPanel dockPanel)
        {
            if (isFirstShow)
            {
                dockPanel.DefaultFloatWindowSize = new Size(this.Size.Width, this.Size.Height);
                base.Show(dockPanel, DockState.Float);
                isFirstShow = false;
            }
            else
            {
                base.Show(dockPanel);
            }
        }

        private void DockActionRecord_Load(object sender, EventArgs e)
        {
            comboBoxMode.SelectedIndex = 0;
            mAutoActionList.AllowNew = true;
            mAutoActionList.AllowRemove = true;
            mAutoActionList.AllowEdit = true;
            dgvAutoGumList.AutoGenerateColumns = true;
            dgvAutoGumList.AllowUserToAddRows = false;
            dgvAutoGumList.DataSource = mAutoActionList;
            ShowParameter();
        }

        internal void ShowParameter()
        {
            txtOriginXSet.Text = originXSet.ToString();
            txtOriginYSet.Text = originYSet.ToString();
            txtPwmCycleTDefault.Text = pwmCycleTDefault.ToString();
            txtPwmCycleTReset.Text = pwmCycleTReset.ToString();
            txtPwmCycleTChabu.Text = pwmCycleTChabu.ToString();
            txtPwmCycleTGum.Text = pwmCycleTGum.ToString();
            txtChabuDelay.Text = pwmChabuDelay.ToString();
        }

        private void SetVisibleAll(bool isVisiable)
        {
            lblPoint1.Visible = isVisiable;
            lblPoint2.Visible = isVisiable;
            lblRadius.Visible = isVisiable;
            lblMode.Visible = isVisiable;
            txtPoint1X.Visible = isVisiable;
            txtPoint1Y.Visible = isVisiable;
            txtPoint2X.Visible = isVisiable;
            txtPoint2Y.Visible = isVisiable;
            txtRadius.Visible = isVisiable;
            comboBoxMode.Visible = isVisiable;
        }

        private void radioButtonMoveTo_Click(object sender, EventArgs e)
        {
            SetVisibleAll(false);
            lblPoint1.Text = "移到坐标";
            lblPoint1.Visible = true;
            txtPoint1X.Visible = true;
            txtPoint1Y.Visible = true;
            btnInsertAction.Text = "移动";
        }

        private void radioButtonDrawLine_Click(object sender, EventArgs e)
        {
            SetVisibleAll(false);
            lblPoint1.Text = "线段起点";
            lblPoint2.Text = "线段终点";
            lblPoint1.Visible = true;
            lblPoint2.Visible = true;
            txtPoint1X.Visible = true;
            txtPoint1Y.Visible = true;
            txtPoint2X.Visible = true;
            txtPoint2Y.Visible = true;
            btnInsertAction.Text = "画直线";
        }

        private void radioButtonDrawArc_Click(object sender, EventArgs e)
        {
            lblPoint1.Text = "圆心坐标";
            SetVisibleAll(true);
            lblPoint2.Visible = false;
            txtPoint2X.Visible = false;
            txtPoint2Y.Visible = false;
            btnInsertAction.Text = "画圆弧";
        }

        private void radioButtonDelay_Click(object sender, EventArgs e)
        {
            SetVisibleAll(false);
            lblPoint1.Text = "延时(ms)";
            lblPoint1.Visible = true;
            txtPoint1X.Visible = true;
            btnInsertAction.Text = "延时";
        }

        private void btnInsertAction_Click(object sender, EventArgs e)
        {
            ActionParas actionParar = new ActionParas();
            int point1X = 0;
            int point1Y = 0;
            int point2X = 0;
            int point2Y = 0;
            int radius = 0;
            int mode = 0;
            int.TryParse(txtPoint1X.Text, out point1X);
            int.TryParse(txtPoint1Y.Text, out point1Y);
            int.TryParse(txtPoint2X.Text, out point2X);
            int.TryParse(txtPoint2Y.Text, out point2Y);
            int.TryParse(txtRadius.Text, out radius);
            mode = comboBoxMode.SelectedIndex + 1;

            actionParar.Point1X = point1X;
            actionParar.Point1Y = point1Y;
            actionParar.Point2X = point2X;
            actionParar.Point2Y = point2Y;
            actionParar.Radius = radius;
            actionParar.Mode = mode;

            if (radioButtonMoveTo.Checked)
            {
                actionParar.Cmd = GUM_ACTION.移动到;
                actionParar.Point2X = 0;
                actionParar.Point2Y = 0;
                actionParar.Radius = 0;
                actionParar.Mode = 0;
            }
            else if (radioButtonDrawLine.Checked)
            {
                actionParar.Cmd = GUM_ACTION.画直线;
                actionParar.Radius = 0;
                actionParar.Mode = 0;
            }
            else if (radioButtonDrawArc.Checked)
            {
                actionParar.Cmd = GUM_ACTION.画圆弧;
                actionParar.Point2X = 0;
                actionParar.Point2Y = 0;
            }
            else if (radioButtonDelay.Checked)
            {
                actionParar.Cmd = GUM_ACTION.延时;
                actionParar.Point1Y = 0;
                actionParar.Point2X = 0;
                actionParar.Point2Y = 0;
                actionParar.Radius = 0;
                actionParar.Mode = 0;
            }

            AddActionPararToList(actionParar);
        }

        private void AddActionPararToList(ActionParas actionParar)
        {
 	        int index = 0;
            if (chkIsReplace.Checked)
            {
                // 替换模式
                if (dgvAutoGumList.SelectedCells.Count != 0)
                {
                    index = dgvAutoGumList.SelectedCells[0].RowIndex;
                    mAutoActionList[index] = actionParar;
                }
                else
                {
                    if (dgvAutoGumList.Rows.Count == 0)
                    {
                        mLog.LogMessage("没有可以替换的指令\n");
                    } 
                    else
                    {
                        mLog.LogMessage("请先选中要替换的行\n");
                    }
                    return;
                }
            }
            else
            {
                // 插入模式
                if (dgvAutoGumList.SelectedCells.Count != 0)
                {
                    index = dgvAutoGumList.SelectedCells[0].RowIndex + 1;
                }
                else
                {
                    index = dgvAutoGumList.Rows.Count;
                }
                mAutoActionList.Insert(index, actionParar);
            }

            // 将当前操作的行设为选定状态
            dgvAutoGumList.ClearSelection();
            dgvAutoGumList.Rows[index].Selected = true;
        }

        private void btnZDown_Click(object sender, EventArgs e)
        {
            ActionParas actionParar = new ActionParas();
            actionParar.Cmd = GUM_ACTION.Z轴压下;
            AddActionPararToList(actionParar);
        }

        private void btnZUp_Click(object sender, EventArgs e)
        {
            ActionParas actionParar = new ActionParas();
            actionParar.Cmd = GUM_ACTION.Z轴抬起;
            AddActionPararToList(actionParar);
        }

        private void btnGumOn_Click(object sender, EventArgs e)
        {
            ActionParas actionParar = new ActionParas();
            actionParar.Cmd = GUM_ACTION.点胶开;
            AddActionPararToList(actionParar);
        }

        private void btnGumOff_Click(object sender, EventArgs e)
        {
            ActionParas actionParar = new ActionParas();
            actionParar.Cmd = GUM_ACTION.点胶关;
            AddActionPararToList(actionParar);
        }

        private void btnClearAllAction_Click(object sender, EventArgs e)
        {
            mAutoActionList.Clear();
        }

        private void btnRemoveActionSelected_Click(object sender, EventArgs e)
        {
            if (dgvAutoGumList.SelectedRows.Count == 0)
            {
                if (dgvAutoGumList.SelectedCells.Count != 0)
                {
                    // 只有部分单元格被选中的情况下删除最近一次选中单元格所在行
                    dgvAutoGumList.Rows.Remove(dgvAutoGumList.SelectedCells[0].OwningRow);
                }
            }
            else
            {
                // 有整行被选中的情况下删除所有被选中行
                foreach (DataGridViewRow row in dgvAutoGumList.SelectedRows)
                {
                    dgvAutoGumList.Rows.Remove(row);
                }
            }
        }

        /// <summary>
        /// 在DataGridView中增加行号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvAutoGumList_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            try
            {
                e.Graphics.DrawString((e.RowIndex + 1).ToString(), e.InheritedRowStyle.Font, new SolidBrush(Color.CadetBlue), e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + 5);
            }
            catch (Exception ex)
            {
                MessageBox.Show("添加行号时发生错误，错误信息：" + ex.Message, "操作失败");
            }
        }

        private void dgvAutoGumList_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            CGumController.mDockMain.DrawAction();
        }

        private void dgvAutoGumList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            CGumController.mDockMain.DrawAction();
        }

        /// <summary>
        /// 将参数信息设置到控制板
        /// </summary>
        public void SendAllPararmeter()
        {
            int count = mAutoActionList.Count;
            ET_GumAction[] actions = new ET_GumAction[count];
            int structLen = System.Runtime.InteropServices.Marshal.SizeOf(typeof(ET_GumAction));
            byte[] bytes = new byte[structLen * count];
            for (int i = 0; i < count; i++)
            {
                actions[i].cmd = (int)mAutoActionList[i].Cmd;
                actions[i].tCoord1.x = mAutoActionList[i].Point1X;
                actions[i].tCoord1.y = mAutoActionList[i].Point1Y;
                actions[i].tCoord2.x = mAutoActionList[i].Point2X;
                actions[i].tCoord2.y = mAutoActionList[i].Point2Y;
                actions[i].r = mAutoActionList[i].Radius;
                actions[i].mode = mAutoActionList[i].Mode;
                Buffer.BlockCopy(CGumController.StructToBytes(actions[i]), 0, bytes, i * structLen, structLen);
            }
            ET_GPES_SENDMSG stSend = new ET_GPES_SENDMSG();
            stSend.CLA = (byte)CLA.CLA_CTRL;
            stSend.INS = (byte)INS.CMD_SET_PARAMETER;
            stSend.sendMsg = new byte[bytes.Length + 32];
            int n = 0;
            stSend.sendMsg[0 + n * 4] = (byte)(originXSet & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(originXSet >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(originXSet >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(originXSet >> 24 & 0xff);
            n = 1;
            stSend.sendMsg[0 + n * 4] = (byte)(originYSet & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(originYSet >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(originYSet >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(originYSet >> 24 & 0xff);
            n = 2;
            stSend.sendMsg[0 + n * 4] = (byte)(pwmCycleTDefault & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(pwmCycleTDefault >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(pwmCycleTDefault >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(pwmCycleTDefault >> 24 & 0xff);
            n = 3;
            stSend.sendMsg[0 + n * 4] = (byte)(pwmCycleTReset & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(pwmCycleTReset >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(pwmCycleTReset >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(pwmCycleTReset >> 24 & 0xff);
            n = 4;
            stSend.sendMsg[0 + n * 4] = (byte)(pwmCycleTGum & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(pwmCycleTGum >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(pwmCycleTGum >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(pwmCycleTGum >> 24 & 0xff);
            n = 5;
            stSend.sendMsg[0 + n * 4] = (byte)(pwmCycleTChabu & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(pwmCycleTChabu >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(pwmCycleTChabu >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(pwmCycleTChabu >> 24 & 0xff);
            n = 6;
            stSend.sendMsg[0 + n * 4] = (byte)(pwmChabuDelay & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(pwmChabuDelay >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(pwmChabuDelay >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(pwmChabuDelay >> 24 & 0xff);
            n = 7;
            stSend.sendMsg[0 + n * 4] = (byte)(count & 0xff);
            stSend.sendMsg[1 + n * 4] = (byte)(count >> 8 & 0xff);
            stSend.sendMsg[2 + n * 4] = (byte)(count >> 16 & 0xff);
            stSend.sendMsg[3 + n * 4] = (byte)(count >> 24 & 0xff);
            Buffer.BlockCopy(bytes, 0, stSend.sendMsg, 32, bytes.Length);
            EnQueueSend(stSend);
        }

        private void btnSetPara_Click(object sender, EventArgs e)
        {
            SendAllPararmeter();
        }

        private void EnQueueSend(ET_GPES_SENDMSG stSend)
        {
            CGumController.mDockSerialProtocol.EnQueueSend(stSend);
        }

        private void txtOriginXSet_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(txtOriginXSet.Text, out originXSet);
            CGumController.mDockMain.DrawAction();
        }

        private void txtOriginYSet_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(txtOriginYSet.Text, out originYSet);
            CGumController.mDockMain.DrawAction();
        }

        private void txtPwmCycleTReset_TextChanged(object sender, EventArgs e)
        {
            uint.TryParse(txtPwmCycleTReset.Text, out pwmCycleTReset);
        }

        private void txtPwmCycleTGum_TextChanged(object sender, EventArgs e)
        {
            uint.TryParse(txtPwmCycleTGum.Text, out pwmCycleTGum);
        }

        private void txtPwmCycleTDefault_TextChanged(object sender, EventArgs e)
        {
            uint.TryParse(txtPwmCycleTDefault.Text, out pwmCycleTDefault);
        }

        private void txtPwmCycleTChabu_TextChanged(object sender, EventArgs e)
        {
            uint.TryParse(txtPwmCycleTChabu.Text, out pwmCycleTChabu);
        }

        private void txtChabuDelay_TextChanged(object sender, EventArgs e)
        {
            uint.TryParse(txtChabuDelay.Text, out pwmChabuDelay);
        }
    }
}
